<?php

namespace app\common\model;

use org\util\HelpUtil;
use think\facade\Session;
use think\facade\Validate;
use think\model\concern\SoftDelete;

class AdminModel extends BaseModel {
    protected $name = 'admin';
    protected $pk = 'id';
    //开启自动写入时间戳
    protected $autoWriteTimestamp = true;
    //视图查询
    public function searchViewAttr($query, $value, $data) {
        //主表
        if (in_array('admin', $value)) {
            $fields = $this->getTableFields('admin');
            $fields = array_merge(array_diff($fields, ['password']));
            $query->view('admin', $fields);
        }
        //部门表
        if (in_array('admin_access', $value)) {
            $query->view('admin_access', 'admin_id,dept_id,site_id,group_id,trade_id', 'admin.id=admin_access.admin_id', 'LEFT');
        }
    }
    /**
     * 获取用户信息
     * @param $map
     * @return array|\PDOStatement|string|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getInfo($map) {
        $info = $this->where($map)->find()->toArray();
        $accessInfo = AdminAccessModel::where('site_id',$this->getLoginInfo('site_id'))
                                      ->where('admin_id',$info['id'])
                                      ->find();
        $info['dept_id'] = $accessInfo['dept_id'];
        $info['group_id'] = $accessInfo['group_id'];
        return $info;
    }

    /**
     * 添加用户
     * @param $data
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function addData($data) {
        try {
            if (!empty($data['username']) && $this->where('username', $data['username'])->find()) {
                exception('该用户名已存在！', 40001);
            }
            if (!empty($data['email']) && $this->where('email', $data['email'])->find()) {
                exception('该邮箱已存在！', 40001);
            }
            if (!empty($data['mobile']) && $this->where('mobile', $data['mobile'])->find()) {
                exception('该手机号已存在！', 40001);
            }
            $data['salt'] = HelpUtil::randString(8);
            $data['password'] = $this->getEncryptPassword($data['password'], $data['salt']);
            $data['session_key'] = isset($data['session_key'])?$data['session_key']:$this->getSessionKey();
            $info = self::create($data,true);
            /*如果不是初始化行业或店铺并且权限id不为空才写入权限表*/
            if(!isset($data['is_init']) && $data['group_id']!=''){
                AdminAccessModel::create([
                    'admin_id'=>$info['id'],
                    'site_id'=>$data['site_id'],
                    'dept_id'=>$data['dept_id'],
                    'group_id'=>$data['group_id'],
                    'trade_id'=>$data['trade_id']
                ]);
            }
        } catch (\Exception $e) {
            exception($e->getMessage());
        }
        return $info;
    }

    /**
     * 修改用户
     * @param $data
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function editData($data) {
        try {
            $info = $this->where('id', $data['id'])->find();
            if ($info['username'] != $data['username']
                && $this->where('username', $data['username'])->find()) {
                exception('该用户名已存在！', 40001);
            }
            if (!empty($data['email'])
                && $info['email'] != $data['email']
                && $this->where('email', $data['email'])->find()) {
                exception('该邮箱已存在！', 40001);
            }
            if (!empty($data['mobile'])
                && $info['mobile'] != $data['mobile']
                && $this->where('mobile', $data['mobile'])->find()) {
                exception('该手机号已存在！', 40001);
            }
            if (empty($data['password'])) {
                unset($data['password']);
            } else {
                $data['password'] = $this->getEncryptPassword($data['password'], $info['salt']);
            }
            $info = self::update($data);
            AdminAccessModel::where('site_id',$data['site_id'])
                            ->where('admin_id',$data['id'])
                            ->update([
                                'admin_id'=>$info['id'],
                                'site_id'=>$data['site_id'],
                                'dept_id'=>$data['dept_id'],
                                'group_id'=>$data['group_id'],
                                'trade_id'=>$data['trade_id']
                            ]);
        } catch (\Exception $e) {
            exception($e->getMessage());
        }
        return true;
    }

    /**
     * 删除用户
     * @param $id
     */
    public function delData($id) {
        $siteId = $this->getLoginInfo('site_id');
        if($this->getSessionKey()=='site'){
            $ownerId = SiteModel::where('id',$siteId)->value('owner_id');
            if($id==$ownerId) exception('不允许删除系统创始人！');
        }else{
            if($id==1) exception('内置用户不允许删除！');
        }
        $count = AdminAccessModel::where('admin_id',$id)->count(); //拥有几家店铺
        if($count==1){ //只有一家店铺删除账号
            $this->where('id',$id)->delete();
        }
        //只删除关联关系
        AdminAccessModel::where('admin_id',$id)->where('site_id',$siteId)->delete();
    }

    /**
     * 获取密码加密后的字符串
     * @param string $password 密码
     * @param string $salt 密码种子
     * @return string
     */
    public function getEncryptPassword($password, $salt = '') {
        return md5(sha1($password) . $salt);
    }

    /**
     * 用户登录
     * @param string $account 账号:用户名、邮箱、手机号
     * @param string $password 密码
     * @return boolean
     */
    public function login($account, $password) {
        $field = $this->getAccountField($account);
        $adminInfo = $this->where($field, $account)->find();
        if (!$adminInfo) exception('用户不存在！', 40001);
        if ($adminInfo['status'] != 1) exception('该账户已禁用！', 40001);
        if ($adminInfo['password'] != $this->getEncryptPassword($password, $adminInfo['salt'])) exception('密码不正确！', 40001);
        //直接登录会员
        $loginInfo = $this->setLoginInfo($adminInfo['id']);
        return $loginInfo;
    }

    /**
     * 退出登录
     * @return bool
     * @throws \Exception
     */
    public function loginOut() {
        $sessionKey = Session::get('session_key');
        Session::delete('session_key');
        Session::delete($sessionKey);
        return true;
    }

    /**
     * 修改密码
     * @param $adminId
     * @param $newPassword
     * @param string $oldPassword
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function changepwd($adminId, $newPassword, $oldPassword = '') {
        $adminInfo = $this->where('id', $adminId)->find();
        //验证旧密码，为空跳过验证直接修改密码
        if ($adminInfo['password'] == $this->getEncryptPassword($oldPassword, $adminInfo['salt']) || $oldPassword == '') {
            $this->where('id', $adminId)->setField('password', $this->getEncryptPassword($newPassword, $adminInfo['salt']));
            $this->loginOut();
        } else {
            exception('原密码不正确！', 40001);
        }
        return true;
    }

    /**
     * 设置登录成功信息
     * @param $adminId
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function setLoginInfo($adminId) {
        //重置所有登录信息
        Session::delete('session_key');
        Session::delete('platform');
        Session::delete('site');
        $map[] = ['id', '=', $adminId];
        $loginInfo = $this->getInfo($map);
        switch ($loginInfo['session_key']) {
            case 'platform': //平台
                $accessInfo = AdminAccessModel::where('site_id',0)
                                              ->where('admin_id',$adminId)
                                              ->find();
                $loginInfo['dept_id'] = $accessInfo['dept_id'];
                $loginInfo['group_id'] = $accessInfo['group_id'];
                if (empty($loginInfo['group_id'])) exception('请联系管理员为您授权!');
                $loginInfo['site_id'] = 0;
                $loginInfo['trade_id'] = DeptModel::where('id',$accessInfo['dept_id'])->value('trade_id');
                break;
            case 'site': //店铺管理员
                $access = AdminAccessModel::field('group_id,site_id,dept_id')
                                          ->where('admin_id', $loginInfo['id'])
                                          ->where('site_id', '>', 0)
                                          ->select();
                if ($access->isEmpty()) exception('请联系店铺管理员为您授权!');
                $access = $access->toArray();
                $count = count($access);
                if($count==1){
                    if((int)$access[0]['group_id']>0){
                        $loginInfo['site_id'] = $access[0]['site_id'];
                        $loginInfo['dept_id'] = $access[0]['dept_id'];
                        $loginInfo['group_id'] = $access[0]['group_id'];
                        $loginInfo['trade_id'] = SiteModel::where('id',$access[0]['site_id'])->value('trade_id');
                    }else{
                        exception('管理员已清除您的权限!');
                    }
                }else{ //多店铺
                    $loginInfo['sites'] = $access;
                }
                break;
            default:
                exception('账户类型不明确！');
                break;
        }
        unset($loginInfo['password'], $loginInfo['salt']);
        $this->where($map)->inc('login_times', 1)->update(['login_time' => time()]);
        Session::set('session_key', $loginInfo['session_key']);
        Session::set($loginInfo['session_key'], $loginInfo);
        return $loginInfo;
    }

    /**
     * 区分账户所属字段
     * @param $account
     * @return string
     */
    public function getAccountField($account) {
        $field = Validate::is($account, 'email') ? 'email' : (Validate::regex($account, '/^1\d{10}$/') ? 'mobile' : 'username');
        return $field;
    }
}